.TITLE DRCIN .IDENT /5.00/ ; ; Copyright (c) 1995-1999 by Mentec, Inc., U.S.A. ; All rights reserved ; ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED ; OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; P. WANNHEDEN 24-MAY-77 ; ; MODIFIED FOR RSX-11M-PLUS VERSION 2 BY: ; ; B. S. MCCARTHY ; ; MODIFIED FOR RSX-11M-PLUS VERSION 2.1 BY: ; ; B. S. MCCARTHY ; ; MODIFIED BY: ; ; J. W. BERZLE 17-OCT-85 5.00 ; ; JWB167 - USE $QRMVA INSTEAD OF $QRMVT ; ; ; MACRO LIBRARY CALLS ; .MCALL HWDDF$,TCBDF$,PCBDF$,ITBDF$ HWDDF$ ; DEFINE HARDWARE REGISTERS TCBDF$ ; DEFINE TCB OFFSETS PCBDF$ ; DEFINE PCB OFFSETS ITBDF$ ; DEFINE ITB OFFSETS ;+ ; **-$DRCIN-CONNECT TO INTERRUPT. ; ; THIS DIRECTIVE INSTRUCTS THE SYSTEM TO CONNECT A SPECIFIED INTERRUPT ; VECTOR TO AN INTERRUPT SERVICE ROUTINE (ISR) IN THE TASK'S OWN SPACE, ; OR TO DISCONNECT A PREVIOUSLY CONNECTED INTERRUPT VECTOR. ; ; IF THE FUNCTION "CONNECT" IS REQUESTED, THE OPERATION IS AS FOLLOWS: ; A BLOCK OF DYNAMIC MEMORY IS ALLOCATED AND SET UP AS AN INTERRUPT ; TRANSFER BLOCK (ITB). THE ITB IS LINKED TO THE ITB LIST OF THE ; TASK WITH LISTHEAD (SINGLE WORD) IN P.DPCB OF THE TASK'S PCB. ; CHECKPOINTING AND SHUFFLING IS DISABLED FOR THE TASK. ; THE VECTOR IS SET UP TO POINT TO THE OFFSET X.JSR IN THE ITB, ; WHICH CONTAINS A SUBROUTINE CALL TO THE SPECIAL INTERRUPT SAVE ; ROUTINE $INTSC. ; ; IF THE FUNCTION "DISCONNECT" IS REQUESTED, THE OPERATION IS ; ESSENTIALLY THE REVERSE OF WHAT IS DESCRIBED FOR "CONNECT". ; ; ************************************************* ; * NOTE - THE DISCONNECT FUNCTION, WHEN * ; * DISCONNECTING THE LAST VECTOR (OR * ; * ONLY), CLEARS THE CHECKPOINT-DISABLE * ; * BIT (PS.CHK) AND NO-SHUFFLE-BIT (PS.NSF) * ; * REGARDLESS OF WHAT THE STATE WAS BEFORE * ; * VECTORS WERE CONNECTED OR ANY CHANGE IN * ; * STATE WHILE VECTORS WERE CONNECTED. * ; * * ; * EXCEPTIONS: * ; * 1. IF THE TASK IS NOT CHECKPOINTABLE, * ; * PS.CHK IS NOT CLEARED. * ; * 2. IF THE TASK IS MARKED FOR ABORT FOR * ; * MEMORY PARITY ERROR, PS.NSF IS NOT CLEARED. * ; ************************************************* ; ; DPB FORMAT: ; ; WD. 00 -- DIC(129.),DPB SIZE(7.). ; WD. 01 -- INTERRUPT VECTOR ADDRESS. ; WD. 02 -- BASE ADDRESS FOR MAPPING OF ISR AND ; ENABLE/DISABLE-INTERRUPT ROUTINES. ; WD. 03 -- ADDRESS OF INTERRUPT SERVICE ROUTINE. IF ZERO, DIRECTIVE ; IS "DISCONNECT FROM INTERRUPTS" AND REMAINING ARGUMENTS ; ARE IGNORED. ; WD. 04 -- ADDRESS OF ENABLE/DISABLE-INTERRUPT ROUTINE. ; WD. 05 -- (LOW BYTE) LOW BYTE OF PSW TO BE SET ; BEFORE CALLING ISR. ; WD. 06 -- ADDRESS OF AST ROUTINE. ; ; INPUTS: ; ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=POINTER TO WD. 01 IN DPB ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK). ; ; IF SUCCESSFUL COMPLETION: ; CC-C 0 ; DIRECTIVE STATUS: ; +1 ; BEFORE RETURN, THE ENABLE/DISABLE-INTERRUPTS ROUTINE ; (IF SPECIFIED) IS CALLED IN KERNEL MODE WITH CC-C CLEAR. ; ; IF DIRECTIVE IS REJECTED: ; CC-C 1 ; DIRECTIVE STATUS: ; D.RS1 AN ITB COULD NOT BE ALLOCATED (NO POOL SPACE). ; D.RS8 THE FUNCTION REQUESTED IS "DISCONNECT" ; AND THE TASK IS NOT OWNER OF THE VECTOR. ; D.RS16 ISSUING TASK IS NOT PRIVILEGED. ; D.RS17 THE SPECIFIED VECTOR IS ALREADY IN USE. ; D.RS19 THE SPECIFIED VECTOR IS ILLEGAL (LOWER THAN 60 ; OR HIGHER THAN HIGHEST VECTOR SPECIFIED AT SYSGEN, ; OR NOT A MULTIPLE OF 4). ; D.RS81 ISR OR ENABLE/DISABLE-INTERRUPT ROUTINE IS NOT ; WITHIN 4K WORDS FROM (BASE ADDRESS & 177700). ;- .IF DF C$$INT .ENABL LSB $DRCIN:: BIT #T3.PRV,T.ST3(R5) ; IS TASK PRIVILEGED? BEQ 95$ ; N - ILLEGAL, JUMP .IF DF M$$PRO BIT $CPBIT,T.RRM(R5) ;DOES TASK HAVE AFFINITY FOR THIS PROCESSOR? BEQ 100$ ;NO IF EQ .ENDC MOV (R3)+,R4 ; GET VECTOR ADDRESS BIT #3,R4 ; MULTIPLE OF 4? BNE 60$ ; N - ILLEGAL VECTOR, JUMP CMP R4,#60 ; VECTOR IN RANGE? BLO 60$ ; N - JUMP CMP R4,#V$$CTR BHIS 60$ ; N - JUMP MOV (R3)+,R0 ; GET BASE ADDRESS MOV (R3)+,-(SP) ; GET ISR ADDRESS BEQ 40$ ; ZERO - DISCONNECT, JUMP ; ; DIRECTIVE IS "CONNECT" ; .IF DF E$$LOG&E$$NSI CMP @R4,#$NS0 ; VECTOR IN USE? BLO 70$ ; Y - ILLEGAL, JUMP CMP @R4,#$NS7 BHI 70$ ; Y - ILLEGAL, JUMP .IFF ; DF E$$LOG&E$$NSI CMP @R4,#$NONSI ; VECTOR IN USE ? BNE 70$ ; Y - ILLEGAL, JUMP .ENDC ; DF E$$LOG&E$$NSI BIC #77,R0 ; CLEAR LOWER 6 BITS IN BASE ADDRESS .IF DF U$$DAS CALL $RELUI ; RELOCATE TO APR 6 ADDRESS .IFF ; DF U$$DAS CALL $RELOC ; RELOCATE TO APR 6 ADDRESS .ENDC ; DF U$$DAS SUB #20000,R2 ; RELOCATE TO APR 5 ADDRESS BCS 90$ ; OUT OF RANGE - JUMP SUB R0,@SP ; GET DISPLACEMENT FROM "BASE" TO "ISR" CMP @SP,#20000 ; .GT. 4K WORDS? BHIS 90$ ; Y - ILLEGAL, JUMP MOV (R3)+,-(SP) ; GET ENB./DIS.INT. ROUTINE ADDRESS BEQ 10$ ; NO SUCH ROUTINE - JUMP SUB R0,@SP ; GET DISPLACEMENT FROM BASE BCS 90$ ; OUT OF RANGE - JUMP CMP @SP,#20000 ; .GT. 4K WORDS? BHIS 90$ ; Y - ILLEGAL, JUMP ADD R2,@SP ; MAKE APR 5 ADDRESSES 10$: ADD R2,2(SP) MOV R1,-(SP) ; SAVE APR 5 VALUE MOV #X.LEN,R1 ; GET SIZE OF ITB IN BYTES .IF DF K$$DAS MOV #$ICAVL-2,R0 CALL $ALOC1 ; ALLOCATE ITB FROM ICB/ITB POOL .IFF CALL $ALOCB ; ALLOCATE AN ITB .ENDC BCS 80$ ; FAILURE - JUMP MOV T.PCB(R5),R1 ; GET TASK'S PCB ADD #P.STAT,R1 ; POINT TO STATUS WORD (P.STAT) BIT #PS.CHK,@R1 ; CHECKPOINTING DISABLED? BNE 20$ ; Y - JUMP BIS #PS.CHK,@R1 ; N - DO IT CLR P.DPCB-P.STAT(R1) ; INITIALIZE ITB LISTHEAD 20$: BIS #PS.NSF,@R1 ; DISABLE SHUFFLING ASSUME P.DPCB,P.STAT-4 TST -(R1) MOV -(R1),@R0 ; ADD ITB TO FRONT OF ITB LIST IN PCB (X.LNK) MOV R0,@R1 TST (R0)+ ; STEP PAST LINK WORD IN ITB MOV R0,R1 ; SAVE INTERRUPT ENTRY POINT MOV #4537,(R0)+ ; "JSR R5,@#$INTSC" (X.JSR) MOV #$INTSC,(R0)+ ; (X.JSR+2) MOV (R3)+,@R0 ; PSW AND UNUSED BYTE (X.PSW) ADD #X.REL-X.PSW,R0 ; POINT TO X.REL IN ITB MOV (SP)+,(R0)+ ; STORE APR 5 VALUE (X.REL) MOV (SP)+,(R0)+ ; STORE ENB./DIS.INT. ROUTINE ADDRESS (X.DSI) MOV R5,(R0)+ ; STORE TCB ADDRESS (X.TCB) MOV (SP)+,X.ISR-(R0) ; STORE ISR ADDRESS (X.ISR) CLR X.FORK+2-(R0) ; CLEAR FORK PC WORD (X.FORK+2) MOV #$DQAC,(R0)+ ; STORE ADDRESS OF ROUTINE TO DEQUEUE ; AST BLOCK QUEUED BY $QASTC TST (R0)+ ; STEP PAST AST QUEUE THREAD WORD MOV PC,(R0)+ ; SET NON-ZERO TO INDICATE ; AST BLOCK FREE (A.CBL) MOV #7*2+2,(R0)+ ; NUMBER OF WORDS TO ALLOCATE ON AST STACK ; (A.BYT) MOV @R3,(R0)+ ; AST ADDRESS (A.AST) MOV #1,(R0)+ ; NUMBER OF AST PARAMETERS = 1 (A.NPR) MOV R4,(R0)+ ; AST PARAMETER = VECTOR ADDRESS (X.VEC) MOV @R4,@R0 ; SAVE VECTOR PC (X.VPC) MOV R1,@R4 ; SET VECTOR TO POINT TO ITB TST -(R1) ; BACK UP TO START OF ITB AND CLEAR CC-C CALLR $CLEDR ;CALL USER ENABLE/DISABLE ROUTINE ; R1 = POINTER TO ITB ; CC-C = 0 TO ENABLE INTERRUPTS, ; = 1 TO DISABLE INTERRUPTS ; ; ; DIRECTIVE IS "DISCONNECT" ; 40$: MOV @R4,R1 ; GET PC FROM VECTOR SUB #X.JSR,R1 ; GET START OF ITB (X.LNK) MOV T.PCB(R5),R0 ; GET PCB BIT #PS.CHK,P.STAT(R0) ; CHECKPOINTING DISABLED? BEQ 100$ ; N - TASK HAS NO ITB'S, JUMP CALL $DISIN ; DISABLE INTERRUPTS, DEALLOCATE THE ; ITB ETCETERA BCS 100$ ; ERROR (TASK IS NOT OWNER OF VECTOR) - JUMP DRSTS +1 ; EXIT WITH SUCCESS 60$: DRSTS D.RS19 ; ILLEGAL VECTOR 70$: DRSTS D.RS17 ; VECTOR ALREADY IN USE 80$: DRSTS D.RS1 ; NO POOL SPACE 90$: DRSTS D.RS81 ; ISR OR ENB./DIS.INT. ROUTINE ADDRESS NOT ; WITHIN RANGE (BASE&177700, BASE&177700+4K) 95$: DRSTS D.RS16 ; PRIVILEGE VIOLATION 100$: DRSTS D.RS8 ; DISCONNECT - TASK IS NOT OWNER OF VECTOR ; ; ;+ ; **-$DISIN-DISCONNECT INTERRUPT VECTOR. ; ; INPUT: ; R1 POINTER TO ITB ; R5 POINTER TO TASK TCB ; ; OUTPUT: ; IF SUCCESS: ; CC-C 0 ; THE FOLLOWING OPERATIONS ARE PERFORMED: ; 1. THE ITB IS REMOVED FROM THE ITB LIST STARTING ; IN P.DPCB OF THE TASK'S PCB. ; 2. IF A USER ROUTINE TO DISABLE INTERRUPTS WAS SUPPLIED ; WHEN THE VECTOR WAS CONNECTED TO, THAT ROUTINE IS CALLED ; IN KERNEL MODE WITH CC-C SET. ; 3. VECTOR PC IS RESTORED TO POINT TO THE NONSENSE INTERRUPT ROUTINE. ; 4. IF THE FORK BLOCK OF THE ITB IS IN THE FORK QUEUE, IT ; IS REMOVED. ; 5. IF THE AST BLOCK OF THE ITB IS IN THE AST QUEUE FOR THE TASK, ; IT IS REMOVED. ; 6. IF THIS WAS THE ONLY VECTOR CONNECTED TO THE TASK, ; AND THE TASK IS CHECKPOINTABLE, CHECKPOINTING IS ENABLED. ; ALSO, UNLESS THE TASK IS MARKED FOR ABORT FOR MEMORY PARITY ; ERROR, SHUFFLING IS ENABLED. ; 7. FINALLY, THE ITB IS DEALLOCATED. ; ; IF ERROR (TASK IS NOT OWNER OF VECTOR): ; CC-C 1 ; ; REGISTERS ALTERED: R0,R1,R2,R3 ;- ; ; $DISIN::MOV T.PCB(R5),R0 ; GET PCB ADD #P.DPCB,R0 ; POINT TO ITB LISTHEAD (P.DPCB) MOV 2(R0),-(SP) ; SAVE WORD FOLLOWING LISTHEAD CALL $QRMVA ; REMOVE FROM ITB LIST MOV (SP)+,2(R0) ; RESTORE WORD FOLLOWING LISTHEAD BCS 130$ ; ITB NOT IN LIST - EXIT WITH ERROR MOV R0,-(SP) ; SAVE POINTER TO ITB LISTHEAD SEC CALL $CLEDR ;CALL USER ROUTINE TO DISABLE INTERRUPTS ; WITH CC-C SET MOV X.VPC(R1),@X.VEC(R1) ; RESTORE VECTOR PC ADD #X.FORK,R1 ; POINT AT FORK BLOCK IN ITB MOV #$FRKHD,R0 ; GET FORK LISTHEAD MTPS #PR7 ; DISABLE INTERRUPTS CALL $QRMVA ;;; REMOVE FROM FORK LIST IF IT IS THERE MTPS #0 ;;; ENABLE INTERRUPTS ADD #X.AST-X.FORK,R1 ; POINT AT AST BLOCK IN ITB MOV R5,R0 ADD #T.ASTL,R0 ; GET AST LIST LISTHEAD CALL $QRMVA ; REMOVE FROM AST LIST IF IT IS THERE SUB #X.AST,R1 ; RESTORE ITB POINTER MOV R1,R0 ; GET ITB POINTER IN R0 MOV (SP)+,R1 ; RESTORE POINTER TO ITB LISTHEAD TST (R1)+ ; ITB LIST NOW EMPTY? BNE 120$ ; N - JUMP ASSUME P.STAT,P.DPCB+4 TST (R1)+ ; POINT TO P.STAT MOV T.ST2(R5),R2 ; Y - GET STATUS WORD 2 FROM TCB BIT #T2.CHK,R2 ; TASK CHECKPOINTABLE? BNE 105$ ; N - JUMP BIC #PS.CHK,@R1 ; ENABLE CHECKPOINTING 105$: ASSUME T2.ABO,100 ROLB R2 ; TASK MARKED FOR ABORT? BPL 110$ ; N - JUMP CMP T.EFLG(R5),#S.PRTY ; Y - IS REASON MEMORY PARITY ERROR? BEQ 120$ ; Y - DON'T MAKE SHUFFLABLE 110$: BIC #PS.NSF,@R1 ; ENABLE SHUFFLING 120$: MOV #X.LEN,R1 ; GET LENGTH OF ITB .IF DF K$$DAS MOV #$ICAVL-2,R3 CALL $DEAC1 ; DEALLOCATE FROM ICB/ITB POOL .IFF CALL $DEACB ; DEALLOCATE ITB .ENDC CLC ; SUCCESS 130$: RETURN .DSABL LSB .ENDC .END